package cn.easyutil.util.javaUtil;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

import org.apache.poi.hslf.HSLFSlideShow;
import org.apache.poi.hslf.model.Slide;
import org.apache.poi.hslf.model.TextRun;
import org.apache.poi.hslf.usermodel.PictureData;
import org.apache.poi.hslf.usermodel.RichTextRun;
import org.apache.poi.hslf.usermodel.SlideShow;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFPictureData;
import org.apache.poi.xslf.usermodel.XSLFShape;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.poi.xslf.usermodel.XSLFTextParagraph;
import org.apache.poi.xslf.usermodel.XSLFTextRun;
import org.apache.poi.xslf.usermodel.XSLFTextShape;

import cn.easyutil.util.javaUtil.bean.MergeImageBean;

public class PPTUtil {

	/**
	 * 将每一页幻灯片转成图片
	 * @param input
	 * @param pptFileName
	 * @return
	 */
	public static List<byte[]> parseToPicture(InputStream input,String pptFileName){
		try {
			if (pptFileName.endsWith(".ppt")) {
				SlideShow show = new SlideShow(input);
				return parsePPTToPicture(show);
			} else if (pptFileName.endsWith(".pptx")) {
				XMLSlideShow show = new XMLSlideShow(input);
				return  parsePPTXToPicture(show);
			}
			throw new RuntimeException("file type not ppt");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 将ppt类型的每一页转成图片
	 * @param show
	 * @return
	 */
	private static List<byte[]> parsePPTToPicture(SlideShow show){
		Dimension pgsize = show.getPageSize();
		Slide[] slide = show.getSlides();
		List<byte[]> list = new ArrayList<byte[]>();
		for (Slide s : slide) {
			TextRun[] truns = s.getTextRuns();
			for (int k = 0; k < truns.length; k++) {
                RichTextRun[] rtruns = truns[k].getRichTextRuns();
                for (int l = 0; l < rtruns.length; l++) {
                    // 原有的字体索引 和 字体名字
//                    int index = rtruns[l].getFontIndex();
//                    String name = rtruns[l].getFontName();
                    // 重新设置 字体索引 和 字体名称 是为了防止生成的图片乱码问题
                    rtruns[l].setFontIndex(1);
                    rtruns[l].setFontName("宋体");
                }

            }
			//根据幻灯片大小生成图片
			BufferedImage img = new BufferedImage(pgsize.width,pgsize.height, BufferedImage.TYPE_INT_RGB);
			Graphics2D graphics = img.createGraphics();
			
			graphics.setPaint(Color.white);
			graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width,pgsize.height));
			s.draw(graphics);
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			try {
				ImageIO.write(img, "jpeg", out);
				list.add(out.toByteArray());
				out.close();
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		return list;
	}
	
	/**
	 * 将pptx类型的每一页转成图片
	 * @param show
	 * @return
	 */
	private static List<byte[]> parsePPTXToPicture(XMLSlideShow show){
		List<byte[]> list = new ArrayList<byte[]>();
		// 获取大小
        Dimension pgsize = show.getPageSize();
        // 获取幻灯片
        List<XSLFSlide> slides = show.getSlides();
        
        for (XSLFSlide xslf : slides) {
        	// 解决乱码问题
            List<XSLFShape> shapes = xslf.getShapes();
            for (XSLFShape shape : shapes) {
                if (shape instanceof XSLFTextShape) {
                    XSLFTextShape sh = (XSLFTextShape) shape;
                    List<XSLFTextParagraph> textParagraphs = sh.getTextParagraphs();
                    for (XSLFTextParagraph xslfTextParagraph : textParagraphs) {
                        List<XSLFTextRun> textRuns = xslfTextParagraph.getTextRuns();
                        for (XSLFTextRun xslfTextRun : textRuns) {
                            xslfTextRun.setFontFamily("宋体");
                        }
                    }
                }
            }
            //根据幻灯片大小生成图片
            BufferedImage img = new BufferedImage(pgsize.width,pgsize.height, BufferedImage.TYPE_INT_RGB);
            Graphics2D graphics = img.createGraphics();

            graphics.setPaint(Color.white);
            graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width,pgsize.height));

            // 最核心的代码
            xslf.draw(graphics);
            
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            try {
            	// 写入到图片中去
            	ImageIO.write(img, "jpeg", out);
            	list.add(out.toByteArray());
            	out.close();
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		return list;
	}
	/**
	 * 读取ppt文件所有图片(非幻灯片)
	 * @param input
	 * @param pptFileName
	 * @return 
	 */
	public static List<byte[]> readImages(InputStream input,String pptFileName){
		try {
			if (pptFileName.endsWith(".ppt")) {
				HSLFSlideShow show = new HSLFSlideShow(input);
				return readPPTImages(show);
			} else if (pptFileName.endsWith(".pptx")) {
				XMLSlideShow show = new XMLSlideShow(input);
				return  readPPTXImages(show);
			}
			throw new RuntimeException("file type not ppt");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 读取ppt文件图片内容
	 * @param show
	 */
	private static List<byte[]> readPPTImages(HSLFSlideShow show){
		List<byte[]> list = new ArrayList<byte[]>();
		PictureData[] ps = show.getPictures();
		for (PictureData p : ps) {
			//读取到ppt中的图片byte
			byte[] pictureData = p.getData();
			list.add(pictureData);
		}
		return list;
	}
	
	/**
	 * 读取pptx文件图片内容
	 * @param show
	 */
	private static List<byte[]> readPPTXImages(XMLSlideShow show){
		List<byte[]> list = new ArrayList<byte[]>();
		List<XSLFPictureData> ps = show.getPictureData();
		for (XSLFPictureData p : ps) {
			//读取到ppt中的图片byte
			byte[] pictureData = p.getData();
			list.add(pictureData);
		}
		return list;
	}
	
	public static void main(String[] args) throws Exception {
		List<byte[]> list = parseToPicture(new FileInputStream(new File("D://11.ppt")), "11.pptx");
		List<MergeImageBean> li = new ArrayList<MergeImageBean>();
		int i = 0;
		for (byte[] bs : list) {
			if(i == 3){
				break;
			}
			if(i == 0){
				MergeImageBean bean = new MergeImageBean();
				bean.setImg(ImageUtil.byteToImg(bs));
				bean.setX(0);
				bean.setY(0);
				bean.setWeight(300);
				bean.setHeight(300);
				li.add(bean);
			}else if(i == 1){
				MergeImageBean bean = new MergeImageBean();
				bean.setImg(ImageUtil.byteToImg(bs));
				bean.setX(0);
				bean.setY(300);
				bean.setWeight(150);
				bean.setHeight(300);
				li.add(bean);
			}else if(i == 2){
				MergeImageBean bean = new MergeImageBean();
				bean.setImg(ImageUtil.byteToImg(bs));
				bean.setX(150);
				bean.setY(300);
				bean.setWeight(150);
				bean.setHeight(300);
				li.add(bean);
			}
			i++;
		}
		byte[] mer = ImageUtil.mergeImage(300, 600, li);
		FileOutputStream out = new FileOutputStream(new File("D:/ppt/合成.png"));
		out.write(mer);
		out.close();
	}
}
